﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using WORD = Microsoft.Office.Interop.Word;
using System.Windows.Xps.Packaging;
using Microsoft.Win32;
using System.IO;
using System.Xml;
using System.IO.Packaging;
using intelliPaper.Model;

namespace intelliSys.Management.Automation.Test
{
    /// <summary>
    /// Interaction logic for DocumentViewer.xaml
    /// </summary>
    public partial class DocumentViewer : UserControl//, IDisposable
    {
        ~DocumentViewer()
        {
            Dispose(false);
        }
        public Question Attached;
        public DocumentViewer()
        {
            this.InitializeComponent();
        }
        public string OpenXmlMarkup
        {
            get
            {
                return openXmlMarkup;
            }
        }
        public XpsDocument XpsDocument
        {
            get
            {
                return xpsDoc;
            }
        }
        private XpsDocument xpsDoc;
        private string openXmlMarkup;
        private bool disposed = false;
        private WORD.Application wordApplication;
        public void Dispose()
        {
            Dispose(false);
            GC.SuppressFinalize(this);
        }
        public string XpsPath
        {
            get
            {
                return xpsPath;
            }
            set
            {
                xpsPath = value;
            }
        }
        public string WordPath
        {
            get
            {
                return wordPath;
            }
            set
            {
                wordPath = value;
            }
        }
        private string xpsPath = System.IO.Directory.GetCurrentDirectory() + "\\temp.xps";
        private string wordPath = System.IO.Directory.GetCurrentDirectory() + "\\temp.docx";
        private void Dispose(bool ManualCalling)
        {
            if (!disposed)
            {
                try
                {
                    wordApplication.Quit(WORD.WdSaveOptions.wdDoNotSaveChanges);
                }
                catch
                {
                }
                ClrState();
            }

            disposed = true;
        }
        private void ClrState()
        {
            if (xpsDoc != null)
            {
                xpsDoc.Close();
            }
            try
            {
                try
                {
                    File.Delete(xpsPath);
                }
                catch
                {
                }
                File.Delete(wordPath);
            }
            catch
            {
            }
        }
        public void Load(string OpenXmlMarkup)
        {
            this.openXmlMarkup = OpenXmlMarkup;
            try
            {
                xpsDoc = ConvertWordDocToXPSDoc(wordPath, xpsPath);
                this.Dispatcher.Invoke(new Action(() =>
                    {
                        Viewer.Document = xpsDoc.GetFixedDocumentSequence();
                        if (OnLoadCompleted != null)
                        {
                            OnLoadCompleted(this, new DocumentViewerLoadStatus() { ex = exception, Status = "Completed" });
                        }
                    }));
            }
            catch (Exception EX)
            {
                try
                {
                    xpsDoc = (new XpsDocument(Directory.GetCurrentDirectory() + "\\default.xps", FileAccess.Read));
                    this.Dispatcher.Invoke(new Action(() =>
                 {
                     Viewer.Document = xpsDoc.GetFixedDocumentSequence();
                 }));
                }
                catch
                {
                }
                this.Dispatcher.Invoke(new Action(() =>
            {
                if (OnLoadCompleted != null)
                {
                    OnLoadCompleted(this, new DocumentViewerLoadStatus() { ex = exception, Status = "Failure" });
                }
            }));
            }
        }
        public void LoadAsync(string OpenXmlMarkup)
        {
            System.Threading.ThreadPool.QueueUserWorkItem((o) =>
                {
                    Load(OpenXmlMarkup);
                });
        }
        public event EventHandler<DocumentViewerLoadStatus> OnLoadCompleted;
        private XpsDocument ConvertWordDocToXPSDoc(string wordDocName, string xpsDocName)
        {
            // Create a WordApplication and add Document to it
            wordApplication = new Microsoft.Office.Interop.Word.Application();
            ClrState();
            XmlDocument xmlDoc = new XmlDocument() { InnerXml = openXmlMarkup };
            var node = xmlDoc.ChildNodes[2];
            var package = Package.Open(wordDocName, FileMode.Create, FileAccess.ReadWrite);
            foreach (XmlNode part in node.ChildNodes)
            {
                var ignoreNodes = part.Attributes["pkg:name"].Value;
                if (ignoreNodes.Contains("style") || ignoreNodes.Contains("setting") || ignoreNodes.Contains("endnote"))
                    continue;
                var pt = package.CreatePart(new System.Uri(part.Attributes["pkg:name"].Value, UriKind.Relative), part.Attributes["pkg:contentType"].Value);
                XmlDocument xmltempDoc = new XmlDocument();
                try
                {
                    xmltempDoc.InnerXml = part.ChildNodes[0].InnerXml;
                    xmltempDoc.Save(pt.GetStream(FileMode.Create, FileAccess.Write));
                }
                catch
                {
                    var x = System.Convert.FromBase64String(part.InnerText);
                    pt.GetStream(FileMode.Create, FileAccess.Write).Write(x, 0, x.Length);
                }
            }
            package.Flush();
            package.Close();
            wordApplication.Documents.Open(wordDocName);
            WORD.Document doc = wordApplication.ActiveDocument;
            // You must make sure you have Microsoft.Office.Interop.Word.Dll version 12.
            // Version 11 or previous versions do not have WdSaveFormat.wdFormatXPS option
            int totalCount = Attached.TrueAnswers.Count + Attached.ErrorAnswers.Count;
            int m = 0, n = 0;
            bool prefix = Attached.QuestionType == "选择题";
            Random randomNum = new Random();
            bool Boldflag = false;
            for (int x = 0; x < totalCount; x++)
            {
                Boldflag = false;
                doc.Paragraphs.Add();
                doc.Paragraphs.Last.Range.Font.Bold = 0;
                var para1 = doc.Paragraphs.Last;
                //还有错误答案则放错误答案
                var rand = randomNum.Next() % 2;
                if (rand == 0)
                {
                    //  bkup.Font = new WORD.Font() { Bold = 0 };
                    if (m < Attached.ErrorAnswers.Count)
                    {
                        if (prefix)
                        {
                            para1.Range.Text = Convert.ToChar('A' + m + n) + "." + Attached.ErrorAnswers[m];
                        }
                        else
                        {
                            para1.Range.Text = Attached.ErrorAnswers[m];
                        }
                        //   bkup.Font = new WORD.Font() { Bold = 0 };
                        m++;
                    }
                    else
                    {
                        Boldflag = true;
                        // bkup.Font = new WORD.Font() { Bold = 1 };
                        if (prefix)
                        {
                            para1.Range.Text = Convert.ToChar('A' + m + n) + "." + Attached.TrueAnswers[n];
                        }
                        else
                        {
                            para1.Range.Text = Attached.TrueAnswers[n];
                        }
                        //para1.Range.Text += "\r";
                        n++;
                    }
                }
                //还有正确答案则放正确答案
                else
                {
                    if (n < Attached.TrueAnswers.Count)
                    {
                        //  bkup.Font = new WORD.Font() { Bold = 1 };
                        if (prefix)
                        {
                            para1.Range.Text = Convert.ToChar('A' + m + n) + "." + Attached.TrueAnswers[n];
                        }
                        else
                        {
                            para1.Range.Text = Attached.TrueAnswers[n];
                        }
                        Boldflag = true;
                        //para1.Range.Text += "\r";
                        n++;
                    }
                    else
                    {
                        //    bkup.Font = new WORD.Font() { Bold = 0 };
                        if (prefix)
                        {
                            para1.Range.Text = Convert.ToChar('A' + m + n) + "." + Attached.ErrorAnswers[m];
                        }
                        else
                        {
                            para1.Range.Text = Attached.ErrorAnswers[m];
                        }
                        Boldflag = false;
                        //  para1.Range.Text += "\r";
                        m++;
                    }
                }
                doc.Paragraphs.Add(para1.Range);
                if (Boldflag)
                    doc.Paragraphs.Last.Range.Font.Bold = 1;
            }
            try
            {
                doc.ExportAsFixedFormat(xpsDocName, WORD.WdExportFormat.wdExportFormatXPS);
                //doc.SaveAs(xpsDocName, WORD.WdSaveFormat.wdFormatXPS);
                XpsDocument xpsDoc = new XpsDocument(xpsDocName, System.IO.FileAccess.Read);
                return xpsDoc;
            }
            catch (Exception exp)
            {
                exception = exp;
            }
            finally
            {
                try
                {
                    doc.Close(WORD.WdSaveOptions.wdDoNotSaveChanges);
                    wordApplication.Quit(WORD.WdSaveOptions.wdDoNotSaveChanges);
                }
                catch
                {

                    exception = new ApplicationException("上次生成的预览未关闭。请再试一次。");
                }
            }
            return null;
        }
        public void Clear()
        {
            ClrState();
            openXmlMarkup = null;
            GC.Collect();
        }
        public Exception exception
        {
            get;
            private set;
        }
    }
    public class DocumentViewerLoadStatus : EventArgs
    {
        public Exception ex
        {
            get;
            set;
        }
        public string Status
        {
            get;
            set;
        }
    }
}